package main

import (
	"fmt"
	"reflect"
	"strconv"
)

func fun1() {
	println("无参数，无返回值函数")
}
func fun2(x int) {
	println("一个参数", x, "无返回值")
}

func fun3(x int, y string) {
	println("两个参数，无返回值")
	println(x, y)
}
func fun4(x int) int {
	//在最后指定返回值类型
	return x
}

// 如果多个参数类型相同，则直接在最后指定类型即可,返回值类型同理
func t(x, y int) (name, age string) {
	fmt.Println(x)
	fmt.Println(y)
	return strconv.Itoa(x), strconv.Itoa(y)
}

/**
TODO 多个返回值
*/
func fun5(x int, y string) (string, bool) {
	return y, x%2 == 0
}

/**
多个参数（不定数量）
numbers在go里称为切片
*/
func fun6(numbers ...int) int {
	total := 0
	for i := 0; i < len(numbers); i++ {
		total += i
	}
	println("求和结果：", total)
	return total
}

/**
具名返回值（指定返回值名）
*/
func fun7(x string, y string) (res1, res2 string) {
	res1 = "hello"
	res2 = "world"
	return x, y
}

/**
具名返回值（指定返回值名），如果return不指定返回值，则默认右括号指定的返回值：res1和res2
*/
func fun8() (res1 int, res2 string) {
	res1 = 1
	res2 = "world"
	return
}

// 递归

func fun9(x int) int {
	if x > 5 {
		return x
	}
	x += 1
	return fun9(x)
}

/**
TODO 接收一个函数参数，格式：(函数名 func(参数 参数类型) 该函数的返回值类型)
*/
func fun10(f func() int) int {
	fmt.Println(f())
	return f()
}

func changenum(arr int) {
	arr = 11
}

// 修改数组值
func changearr(arr [3]int) {
	arr[0] = 11
}

// 接收指针
func changeArr2(arr *[3]int) {
	arr[0] = 11
}
func changeNum(i *int) {
	*i = *i + 1
	// i 存放的时原参数的地址
	fmt.Println("changNum i 的地址:", &i)
}
func changemap(arr map[string]int) {
	arr["a"] = 11
}

// 自定义数据类型
func cusData() {
	type cusInt int

	var x cusInt
	x = 1
	fmt.Println("cusInt x:0", x)

	var y int
	y = 2
	//不能将 y 赋值给 x，虽然x 自定义类型也是 int，但 go 认为是两种类型
	//x=y
	fmt.Println("y:", y)

	// 定义一个函数类型
	type myFun func(a, b int) int
}

func main() {
	////这是数组
	//var arr2 = [3]int{1, 2, 3}
	//// 这是切片 切片[]没有长度
	//var slice = []int{1, 2, 3}
	var slice2 = make([]int, 0, 2)
	//fmt.Println(slice)
	//map1 := make(map[string]int, 2)
	//map1["a"] = 1
	//changearr(arr2)
	////1 函数内修改不影响原数组值，说明是值传递
	//fmt.Println(arr2[0])
	//changeArr2(&arr2)
	////11 通过传递地址，实现引用传递，原数组值被修改
	//fmt.Println(arr2[0])
	//changemap(map1)
	////11 函数内修改 map 的值，函数外原变量也修改了，说明是引用传递
	//fmt.Println(map1["a"])
	//
	//var i int = 1
	//fmt.Println("i 的地址", &i)
	//changeNum(&i)
	//append()
	//fmt.Println(i)
	fmt.Println(reflect.TypeOf(slice2))

	changeSlice(slice2)
	fmt.Println(slice2)
}

func changeSlice(slice []int) {
	slice = append(slice, 7)
	slice = append(slice, 7)
}
